package com.moyu.user.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.moyu.common.core.domain.PermissionDTO;
import com.moyu.common.core.domain.R;
import com.moyu.common.core.enums.ResultCode;
import com.moyu.common.redis.service.RedisService;
import com.moyu.common.security.exception.ServiceException;
import com.moyu.common.security.service.TokenService;
import com.moyu.user.domain.permission.Permission;
import com.moyu.user.domain.role.Role;
import com.moyu.user.domain.user.User;
import com.moyu.user.mapper.UserMapper;
import com.moyu.user.service.IPermissionService;
import com.moyu.user.service.IRoleService;
import com.moyu.user.service.IUserService;
import com.moyu.user.utils.BCryptUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * @Author 赵彦博
 * @Date 2024/11/19 11:02
 */
@Service
@RefreshScope
public class UserServiceImpl implements IUserService {

    @Autowired
    private UserMapper userMapper;

    @Value("${jwt.secret}")
    private String secret;

    @Autowired
    private IRoleService roleService;

    @Autowired
    private RedisService redisService;

    @Autowired
    private TokenService tokenService;

    @Autowired
    private IPermissionService permissionService;


    @Override
    public User query(String username) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        User user = userMapper.selectOne(queryWrapper
                .select(User::getId, User::getUsername, User::getPassword, User::getFullName)
                .eq(User::getUsername, username));
        return user;
    }

    @Override
    public R<String> login(String username, String password) {
        // 通过用户名去数据库中查询，对应的用户信息
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        User user = query(username);
        if (user == null) {
            return R.fail(ResultCode.FAILED_USER_NOT_EXISTS);
        }
        if (BCryptUtils.matchesPassword(password, user.getPassword())) {
            // TODO 根据分配的权限，存储redis和token
            List<Permission> permissions = permissionService.listByUsername(username, false);
            List<PermissionDTO> permissionDTOS = new ArrayList<>();
            for (int i = 0; i < permissions.size(); i++) {
                PermissionDTO permissionDTO = new PermissionDTO();
                permissionDTO.setId(permissions.get(i).getId());
                permissionDTO.setName(permissions.get(i).getName());
                permissionDTO.setRouterName(permissions.get(i).getRouterName());
                permissionDTO.setRouterPath(permissions.get(i).getRouterPath());
                permissionDTOS.add(permissionDTO);
            }
            String token = tokenService.createToken(user.getId(), secret, permissionDTOS);
            return R.ok(token);
        }
        return R.fail(ResultCode.FAILED_LOGIN);
    }

    @Override
    public User createUser(User user) {
        // 通过用户名去数据库中查询，对应的用户信息
        User dataUser = query(user.getUsername());
        if (dataUser != null) {
            throw new ServiceException(ResultCode.AILED_USER_EXISTS);
        }
        String rawPassword = user.getPassword();
        if (rawPassword != null) {
            user.setPassword(BCryptUtils.encryptPassword(rawPassword));
        }
        userMapper.insert(user);
        if (user.getRoles() == null || user.getRoles().size() == 0) return user;
        userMapper.insertRole(user.getId(), user.getRoles());
        return user;
    }

    @Override
    public User update(User user) {
        User oldUser = query(user.getUsername());
        if (oldUser != null && !oldUser.getUsername().equals(user.getUsername())) {
            throw new ServiceException(ResultCode.AILED_USER_EXISTS);
        }
        String rawPassword = user.getPassword();
        if (rawPassword != null) {
            user.setPassword(BCryptUtils.encryptPassword(rawPassword));
        }
        userMapper.update(user);
        long id = user.getId();
        List<Role> roles = roleService.listByUsername(user.getUsername());
        if (roles == null || roles.size() == 0) return query(user.getUsername());
        userMapper.deleteRole(id);
        userMapper.insertRole(id, roles);
        return query(user.getUsername());
    }


    @Override
    public boolean delete(Long id) {
        userMapper.deleteRole(id);
        return userMapper.delete(id) > 0;
    }

    @Override
    public List<Role> listRoleByUsername(String username) {
        return roleService.listByUsername(username);
    }

    @Override
    public PageInfo<User> list(int pageNumber, int pageSize) {
        PageHelper.startPage(pageNumber, pageSize);
        return PageInfo.of(userMapper.list());
    }

}
